import static org.junit.Assert.*;

import java.util.HashMap;
import java.util.Map;

import org.junit.Before;
import org.junit.Test;

public class TestDijkstras {
	//Graph file
	SimpleGraph graph;
    
	//Expected weights of paths from A and J.  These
	//values found using a python graph library, so they
	//should be accurate.
	Map<String, Integer> expectedWeightsFromA;
	Map<String, Integer> expectedWeightsFromJ;
	
	// Expected shortest path from Q to B
	// We test this by running Dijkstras on "B" and working
	// our way back from Q to B (as the shortest path is
	// the same both directions on an undirected graph).
	String[] QtoB = new String[] { "Q", "P", "M", "L", "K", "B" };
	
	@Before
	public void setup() {
		graph = new SimpleGraph();
	    GraphInput.LoadSimpleGraph(graph, "graph.txt");
	    
		expectedWeightsFromA = new HashMap<String, Integer>();
		expectedWeightsFromA.put("A", 0);
		expectedWeightsFromA.put("B", 4);
		expectedWeightsFromA.put("C", 8);
		expectedWeightsFromA.put("D", 9);
		expectedWeightsFromA.put("E", 7);
		expectedWeightsFromA.put("F", 13);
		expectedWeightsFromA.put("G", 12);
		expectedWeightsFromA.put("H", 13);
		expectedWeightsFromA.put("I", 9);
		expectedWeightsFromA.put("J", 8);
		expectedWeightsFromA.put("K", 7);
		expectedWeightsFromA.put("L", 10);
		expectedWeightsFromA.put("M", 12);
		expectedWeightsFromA.put("N", 13);
		expectedWeightsFromA.put("O", 17);
		expectedWeightsFromA.put("P", 15);
		expectedWeightsFromA.put("Q", 22);
		expectedWeightsFromA.put("R", 17);
		
		expectedWeightsFromJ = new HashMap<String, Integer>();
		expectedWeightsFromJ.put("A", 8);
		expectedWeightsFromJ.put("B", 4);
		expectedWeightsFromJ.put("C", 4);
		expectedWeightsFromJ.put("D", 2);
		expectedWeightsFromJ.put("E", 4);
		expectedWeightsFromJ.put("F", 9);
		expectedWeightsFromJ.put("G", 5);
		expectedWeightsFromJ.put("H", 6);
		expectedWeightsFromJ.put("I", 1);
		expectedWeightsFromJ.put("J", 0);
		expectedWeightsFromJ.put("K", 1);
		expectedWeightsFromJ.put("L", 4);
		expectedWeightsFromJ.put("M", 6);
		expectedWeightsFromJ.put("N", 7);
		expectedWeightsFromJ.put("O", 11);
		expectedWeightsFromJ.put("P", 9);
		expectedWeightsFromJ.put("Q", 16);
		expectedWeightsFromJ.put("R", 11);
	}

	@Test
	public void testDijkstrasWeights() {
        Map<String, DijkstrasNode> fromA = Dijkstras.dijsktras(graph, "A");
        Map<String, DijkstrasNode> fromJ = Dijkstras.dijsktras(graph, "J");        
        for (String node : fromA.keySet()) {
        	assertSame(expectedWeightsFromA.get(node), fromA.get(node).getLabel());
        	assertSame(expectedWeightsFromJ.get(node), fromJ.get(node).getLabel());
        }
	}
	
	@Test
	public void testDijkstrasPath() {
        Map<String, DijkstrasNode> fromQ = Dijkstras.dijsktras(graph, "B");
        DijkstrasNode node = fromQ.get("Q");
        Vertex vert = node.getCurrentVertex();
        int i = 0;
        while (vert != null) {
        	assertEquals(QtoB[i], vert.getName());
        	vert = node.getPreviousVertex();
        	if (vert != null) {
        		node = fromQ.get(vert.getName());
        	}
        	i++;
        }
	}
}
